package com.speechb.modules.config;

import com.speechb.common.file.PropertyUtils;
import com.speechb.modules.shiro.CustomShiroRealm;
import com.speechb.modules.shiro.MySessionManager;
import com.speechb.modules.shiro.RedisSessionDAO;
import com.speechb.modules.shiro.matcher.CustomCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.IOException;

@Configuration
public class ShiroConfig {
    private static final String SHIRO_CONFIG = "config/shiro-config.properties";
    private static Logger logger= LoggerFactory.getLogger(ShiroConfig.class);
    //将自己的验证方式加入容器
    @Bean
    public CustomShiroRealm customShiroRealm(CustomCredentialsMatcher customCredentialsMatcher) {
        CustomShiroRealm myShiroRealm = new CustomShiroRealm();
        myShiroRealm.setCredentialsMatcher(customCredentialsMatcher);
        return myShiroRealm;
    }

    @Bean
    public SessionDAO redisSessionDAO(RedisTemplate redisTemplate) {
        return new RedisSessionDAO(redisTemplate);
    }

    @Bean
    public MySessionManager mySessionManager(RedisTemplate redisTemplate) {
        return new MySessionManager(redisTemplate);
    }


    //权限管理，配置主要是Realm的管理认证
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(CustomShiroRealm customRealm, SessionDAO redisSessionDAO, MySessionManager mySessionManager) {
        DefaultWebSecurityManager  securityManager = new DefaultWebSecurityManager ();
        securityManager.setSessionManager(mySessionManager);
        securityManager.setRealm(customRealm);
        //获取SessionManager
        DefaultWebSessionManager sessionManager = (DefaultWebSessionManager)securityManager.getSessionManager();
        sessionManager.setSessionDAO(redisSessionDAO);
        return securityManager;
    }



    //Filter工厂，设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        shiroFilterFactoryBean.setLoginUrl("/admin/login");
        //首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //错误页面，认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        try {
            shiroFilterFactoryBean.setFilterChainDefinitionMap(PropertyUtils.propertiesToMap(SHIRO_CONFIG));
        } catch (IOException e) {
            logger.error("failed to load shiro-config.properties file",e);
        }
        return shiroFilterFactoryBean;
    }

    @Bean
    public CacheManager cacheManager(){
        return new EhCacheManager();
    }


//    @Bean("sessionDAO")
//    public SessionDAO sessionDAO(){
//        logger.warn("MyEnterpriseCacheSessionDAO来了");
//        return new MyEnterpriseCacheSessionDAO();
//    }

//    @Bean
//    public SessionManager sessionManager(SessionDAO sessionDAO){
//        DefaultWebSessionManager manager = new DefaultWebSessionManager();
//        manager.setSessionDAO(sessionDAO);
//        manager.setGlobalSessionTimeout(3600000);
//        manager.setSessionValidationInterval(3600000);
//        return manager;
//    }
    @Bean("customCredentialsMatcher")
    public CustomCredentialsMatcher customCredentialsMatcher() {
        return new CustomCredentialsMatcher();
    }

    /**
     * 开启shiro 注解模式
     * 可以在controller中的方法前加上注解
     * 如 @RequiresPermissions("userInfo:add")
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}